From 8ed725bad8af39aa1af3fd9e3f6a90225dab437b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 8 Oct 2010 01:37:33 -0400 Subject: [PATCH] Get scrollbars out of the way of the window's resize grip If there are both horizontal and vertical scrollbars, there is an unused 'corner' into which the resize grip fits. Individual scrollbars need to be shortened and moved to make room for the resize grip. --- gtk/gtkrange.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 4 deletions(-) diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index fd9ae0e175..ab363419f6 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -37,6 +37,7 @@ #include "gtkrange.h" #include "gtkscale.h" #include "gtkscrollbar.h" +#include "gtkwindow.h" #include "gtkprivate.h" #include "gtkintl.h" @@ -185,6 +186,8 @@ static void gtk_range_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_range_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +static void gtk_range_hierarchy_changed (GtkWidget *widget, + GtkWidget *previous_toplevel); static void gtk_range_realize (GtkWidget *widget); static void gtk_range_unrealize (GtkWidget *widget); static void gtk_range_map (GtkWidget *widget); @@ -215,6 +218,8 @@ static void update_slider_position (GtkRange *range, gint mouse_x, gint mouse_y); static void stop_scrolling (GtkRange *range); +static gboolean modify_allocation_for_window_grip (GtkWidget *widget, + GtkAllocation *allocation); /* Range methods */ @@ -290,8 +295,9 @@ gtk_range_class_init (GtkRangeClass *class) widget_class->destroy = gtk_range_destroy; widget_class->size_request = gtk_range_size_request; widget_class->size_allocate = gtk_range_size_allocate; + widget_class->hierarchy_changed = gtk_range_hierarchy_changed; widget_class->realize = gtk_range_realize; - widget_class->unrealize = gtk_range_unrealize; + widget_class->unrealize = gtk_range_unrealize; widget_class->map = gtk_range_map; widget_class->unmap = gtk_range_unmap; widget_class->draw = gtk_range_draw; @@ -1560,7 +1566,7 @@ gtk_range_size_request (GtkWidget *widget, &stepper_spacing, NULL, NULL, NULL); - gtk_range_calc_request (range, + gtk_range_calc_request (range, slider_width, stepper_size, focus_width, trough_border, stepper_spacing, &range_rect, &border, NULL, NULL, NULL, NULL); @@ -1569,6 +1575,65 @@ gtk_range_size_request (GtkWidget *widget, requisition->height = range_rect.height + border.top + border.bottom; } +static gboolean +modify_allocation_for_window_grip (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkRange *range = GTK_RANGE (widget); + GtkRangePrivate *priv = range->priv; + GtkWidget *window; + GdkRectangle grip_rect; + GdkRectangle translated_rect; + gint x; + gint y; + + window = gtk_widget_get_toplevel (widget); + if (!GTK_IS_WINDOW (window)) + return FALSE; + + if (!gtk_window_resize_grip_is_visible (GTK_WINDOW (window))) + return FALSE; + + /* Get the area of the window's corner grip */ + gtk_window_get_resize_grip_area (GTK_WINDOW (window), &grip_rect); + + x = 0; + y = 0; + + /* Translate the stepper's area into window coords */ + if (gtk_widget_translate_coordinates (gtk_widget_get_parent (widget), + window, + allocation->x, + allocation->y, + &x, + &y)) + { + translated_rect.x = x; + translated_rect.y = y; + translated_rect.width = allocation->width; + translated_rect.height = allocation->height; + + /* If the stepper button intersects the window resize grip.. */ + if (gdk_rectangle_intersect (&grip_rect, &translated_rect, NULL)) + { + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) + { + allocation->width -= grip_rect.width; + if (gtk_widget_get_direction (window) == GTK_TEXT_DIR_RTL) + allocation->x += grip_rect.width; + } + else + { + allocation->height -= grip_rect.height; + } + + return TRUE; + } + } + + return FALSE; +} + static void gtk_range_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -1576,6 +1641,7 @@ gtk_range_size_allocate (GtkWidget *widget, GtkRange *range = GTK_RANGE (widget); GtkRangePrivate *priv = range->priv; + modify_allocation_for_window_grip (widget, allocation); gtk_widget_set_allocation (widget, allocation); priv->recalc_marks = TRUE; @@ -1589,6 +1655,30 @@ gtk_range_size_allocate (GtkWidget *widget, allocation->width, allocation->height); } +static void +resize_grip_visible_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + gtk_widget_queue_resize (GTK_WIDGET (user_data)); +} + +static void +gtk_range_hierarchy_changed (GtkWidget *widget, + GtkWidget *previous_toplevel) +{ + GtkWidget *window; + + if (previous_toplevel) + g_signal_handlers_disconnect_by_func (previous_toplevel, + G_CALLBACK (resize_grip_visible_changed), + widget); + window = gtk_widget_get_toplevel (widget); + if (GTK_IS_WINDOW (window)) + g_signal_connect (window, "notify::resize-grip-visible", + G_CALLBACK (resize_grip_visible_changed), widget); +} + static void gtk_range_realize (GtkWidget *widget) { @@ -1597,10 +1687,10 @@ gtk_range_realize (GtkWidget *widget) GtkRangePrivate *priv = range->priv; GdkWindow *window; GdkWindowAttr attributes; - gint attributes_mask; + gint attributes_mask; gtk_range_calc_layout (range, priv->adjustment->value); - + gtk_widget_set_realized (widget, TRUE); window = gtk_widget_get_parent_window (widget); @@ -1608,6 +1698,8 @@ gtk_range_realize (GtkWidget *widget) g_object_ref (window); gtk_widget_get_allocation (widget, &allocation); + if (modify_allocation_for_window_grip (widget, &allocation)) + gtk_widget_set_allocation (widget, &allocation); attributes.window_type = GDK_WINDOW_CHILD; attributes.x = allocation.x; -- 2.30.2